﻿using System;
using System.Collections;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace TSharp.Core.Aop.Handler
{
	/// <summary>
	/// 验证处理类
	/// </summary>
	public class ValidationHandler : ICallHandler
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="ValidationHandler"/> class.
		/// </summary>
		/// <param name="type">The type.</param>
		/// <param name="order">The order.</param>
		public ValidationHandler(Type type, int order)
		{
			Type = type;
			Order = order;
		}

		/// <summary>
		/// 验证类型名称
		/// </summary>
		public Type Type { get; set; }

		/// <summary>
		/// 换行符
		/// </summary>
		public static string NewLine { get; set; }

		#region ICallHandler Members

		/// <summary>
		/// Order in which the handler will be executed
		/// </summary>
		/// <value></value>
		public int Order { get; set; }

		/// <summary>
		/// Implement this method to execute your handler processing.
		/// </summary>
		/// <param name="input">Inputs to the current call to the target.</param>
		/// <param name="getNext">Delegate to execute to get the next delegate in the handler
		/// chain.</param>
		/// <returns>Return value from the target.</returns>
		public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
		{
			//验证方法的参数
			PreCall(input);
			//验证目标对象
			if (Type != null)
				Validate(ValidationFactory.CreateValidator(Type), input.Target);
			return getNext()(input, getNext);
		}

		#endregion

		/// <summary>
		/// 方法执行前 验证参数
		/// </summary>
		/// <param name="input">The input.</param>
		private void PreCall(IMethodInvocation input)
		{
			for (int i = 0; i < input.Inputs.Count; ++i)
			{
				object obj = input.Inputs[i];
				var irbl = obj as IEnumerable;
				//如果输入参数是列表
				if (irbl != null)
				{
					IEnumerator ir = irbl.GetEnumerator();
					while (ir.MoveNext())
					{
						object cur = ir.Current;
						Validator validator = ValidationFactory.CreateValidator(cur.GetType());
						Validate(validator, cur);
					}
				}
					//字符串则要进行防止sql注入
				else if (obj is string)
				{
				}
					//排除值类型的验证，
				else if (obj is Nullable)
				{
					Validator validator = ValidationFactory.CreateValidator(obj.GetType());
					Validate(validator, obj);
				}
			}
		}

		/// <summary>
		/// 对关键字进行转义
		/// </summary>
		/// <param name="keyword">关键字</param>
		/// <returns>转义后的关键字</returns>
		/// <remarks></remarks>
		public static string EscapeKeyword(string keyword)
		{
			// 注意：不要打乱现有顺序
			keyword = keyword.Replace("'", "''");
			keyword = keyword.Replace("[", "[[]");
			keyword = keyword.Replace("%", "[%]");
			keyword = keyword.Replace("_", "[_]");
			return keyword;
		}

		/// <summary>
		/// Validates the specified validator.
		/// </summary>
		/// <param name="validator">The validator.</param>
		/// <param name="target">The target.</param>
		public void Validate(Validator validator, object target)
		{
			ValidationResults results = validator.Validate(target);
			if (!results.IsValid)
			{
				var sb = new StringBuilder();
				foreach (ValidationResult result in results)
				{
					sb.Append("关键字 = " + result.Key + NewLine);
					sb.Append("消息 = " +
					          result.Message + NewLine);
				}
				throw new InvalidOperationException(sb.ToString());
			}
		}
	}
}